import numpy as np


class MyVector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.theta = np.arctan2(y, x)
        self._length = np.sqrt(x**2 + y**2)

    def get(self):
        my_tuple = tuple([self.x, self.y])
        return my_tuple

    def __add__(self, other):
        return MyVector(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return MyVector(self.x - other.x, self.y - other.y)

    def __mul__(self, scalar):
        return MyVector(scalar * self.x, scalar * self.y)

    def __rmul__(self, scalar):
        return self.__mul__(scalar)

    @property
    def length(self):
        return self._length

    @property
    def unit_vector(self):
        return MyVector(self.x / self.length, self.y / self.length)


def from_angle_and_length(angle_radians, length):
    x = length * np.cos(angle_radians)
    y = length * np.sin(angle_radians)
    return MyVector(x, y)


def from_x_and_theta(x, theta):
    y = x * np.tan(theta)
    return MyVector(x, y)


def from_y_and_theta(y, theta):
    x = y / np.tan(theta)
    return MyVector(x, y)


def from_x_and_length(x, length, direction="+"):
    if x > length:
        raise ValueError("x cannot be more than length")
    if direction == "+":
        y = np.sqrt(length**2 - x**2)
    elif direction == "-":
        y = -np.sqrt(length**2 - x**2)
    else:
        raise ValueError("wrong direction")
    return MyVector(x, y)


def from_y_and_length(y, length, direction="+"):
    if y > length:
        raise ValueError("y cannot be more than length")
    if direction == "+":
        x = np.sqrt(length**2 - y**2)
    elif direction == "-":
        x = -np.sqrt(length**2 - y**2)
    else:
        raise ValueError("wrong direction")
    return MyVector(x, y)


def from_k(k, m_vector):
    return MyVector(k * m_vector.x, k * m_vector.y)


def my_vector_addition(v1, v2):
    return MyVector(v1.x + v2.x, v1.y + v2.y)


def my_vector_subtraction(v1, v2):
    return MyVector(v1.x - v2.x, v1.y - v2.y)


def project_and_perpendicular(v1, v2):
    """
    计算向量v1在向量v2上的投影分量以及垂直分量。

    参数:
    v1 (MyVector): 第一个向量
    v2 (MyVector): 第二个向量

    返回:
    tuple: 包含投影分量和垂直分量的元组
    """
    # 计算点积
    dot_product = v1.x * v2.x + v1.y * v2.y
    # 计算v2的长度
    v2_length = v2.length
    # 计算投影分量
    projection = dot_product / v2_length
    # 计算v2的单位向量
    v2_unit = v2.unit_vector
    # 计算投影分量向量
    projection_vector = projection * v2_unit
    # 计算垂直分量向量
    perpendicular_vector = v1 - projection_vector
    return (projection_vector, perpendicular_vector)


y_basis = MyVector(0, 1)
x_basis = MyVector(1, 0)
